package com.egg.basic.controller.feign;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.egg.basic.enums.sms.SmsTypeEnum;
import com.egg.basic.fegin.BasicSmsFeignClient;
import com.egg.common.core.model.controller.FeignController;
import com.egg.common.core.model.response.ResponseData;
import com.egg.common.redis.util.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;


@Slf4j
@Api(tags = FeignController.API_PREFIX + "短信服务")
@RestController
@RequestMapping("/sms")
public class FeignSmsController extends FeignController implements BasicSmsFeignClient {


    @Autowired(required = false)
    public Client client;


    /**
     * 构建KEY
     *
     * @param phone
     * @param smsType
     * @return
     */
    private String buildKey(String phone, SmsTypeEnum smsType) {
        return String.format("basic:sms:ali:send:%s:%s:%s", phone, smsType.getTemplate(), smsType.getSign());
    }

    /**
     * 创建CODE
     *
     * @param phone
     * @param smsType
     * @return
     */
    private String createCode(String phone, SmsTypeEnum smsType) {
        Integer code = RandomUtil.randomInt(100000, 999999);
        String key = buildKey(phone, smsType);
        RedisUtil.set(key, code.toString(), 300);
        return code.toString();
    }

    /**
     * 获取阿里CODE
     *
     * @param phone
     * @param smsType
     * @return
     */
    private String getCode(String phone, SmsTypeEnum smsType) {
        String key = buildKey(phone, smsType);
        String code = RedisUtil.get(key);
        if (ObjectUtil.isNotEmpty(code)) {
            RedisUtil.delete(key);
        }
        return code;
    }

    @Override
    @ApiOperation(value = "发送短信验证码")
    @GetMapping("/code/send")
    public ResponseData<String> sendSms(
            @ApiParam(value = "手机号码", required = true) @RequestParam(value = "phone") String phone
            , @ApiParam(value = "业务类型", required = true) @RequestParam(value = "smsType") SmsTypeEnum smsType
    ) {
        if (ObjectUtil.isEmpty(phone) || ObjectUtil.isEmpty(smsType)) {
            return ResponseData.error("必填参数缺失");
        }
        SendSmsRequest sendSmsRequest = new SendSmsRequest();
        sendSmsRequest.setPhoneNumbers(phone);
        sendSmsRequest.setSignName(smsType.getSign());
        sendSmsRequest.setTemplateCode(smsType.getTemplate());
        JSONObject jsonCode = new JSONObject();
        String code = createCode(phone, smsType);
        jsonCode.put("code", code);
        sendSmsRequest.setTemplateParam(jsonCode.toJSONString());
        SendSmsResponse sendSmsResponse;
        try {
            sendSmsResponse = client.sendSms(sendSmsRequest);
            if (!Objects.equals(sendSmsResponse.getBody().getCode().toLowerCase(), "ok")) {
                log.error("发送短信验证码手机号 {} 发送失败原因 {}", phone, sendSmsResponse.getBody().getMessage());
            }
        } catch (Exception e) {
            log.error("发送短信验证码手机号 {} 发送失败原因 {}", phone, e.getMessage());
        }
        log.info("发送短信验证码手机号 {} 验证码 {}", phone, code);
        return ResponseData.success();
    }

    @Override
    @ApiOperation(value = "验证短信码验证")
    @GetMapping("/code/verify")
    public ResponseData<Boolean> verifySms(
            @ApiParam(value = "手机号码", required = true) @RequestParam(value = "phone") String phone
            , @ApiParam(value = "业务类型", required = true) @RequestParam(value = "smsType") SmsTypeEnum smsType
            , @ApiParam(value = "验证码", required = true) @RequestParam(value = "verifyCode") String verifyCode
    ) {
        if (ObjectUtil.isEmpty(phone) || ObjectUtil.isEmpty(smsType) || ObjectUtil.isEmpty(verifyCode)) {
            return ResponseData.error("必填参数缺失");
        }
        String code = getCode(phone, smsType);
        if (ObjectUtil.isEmpty(code)) {
            return ResponseData.success(false);
        }
        boolean verify = Objects.equals(verifyCode, code);
        return ResponseData.success(verify);
    }


}

